﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using System.Windows.Forms;
using EnvDTE;
using System.Runtime.InteropServices;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;

namespace BuildTasks
{
    public class ZipTemplates : ITask
    {
        public IBuildEngine BuildEngine { get; set; }
        public ITaskHost HostObject { get; set; }

        public bool Execute()
        {
            try
            {
                var projectFile = new FileInfo(this.BuildEngine.ProjectFileOfTaskNode);
                var templateLocation = new DirectoryInfo(Path.Combine(projectFile.Directory.Parent.FullName, @"CodeGenerationPipeline\VSTemplates"));

                Console.WriteLine("Zipping templates");

                foreach (var subDir in templateLocation.GetDirectories())
                {
                    if (subDir.Name != "CommonFiles")
                    {
                        Console.WriteLine("Zipping " + subDir.Name);

                        var fileInfo = new FileInfo(Path.Combine(subDir.FullName, subDir.Name + ".zip"));

                        using (var stream = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite))
                        {
                            using (var zipStream = new ZipOutputStream(stream))
                            {
                                Recurse(subDir, zipStream, subDir.FullName);
                            }
                        }
                    }
                }

                Console.WriteLine("Finished zipping templates successfully");
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Error zipping templates: '{0}'", ex.Message));
                return false;
            }

            return true;
        }

        private void Recurse(DirectoryInfo directory, ZipOutputStream zipStream, string rootPath)
        {
            foreach (var file in directory.GetFiles())
            {
                if (file.Extension.ToLower() != ".zip")
                {
                    var name = file.FullName.Remove(0, rootPath.Length + (rootPath.EndsWith(@"\") ? 0 : 1));
                    var entry = new ZipEntry(name);

                    zipStream.PutNextEntry(entry);

                    using (var inputStream = File.Open(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write))
                    {
                        byte[] buffer = new byte[2048];
                        int length;

                        while ((length = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            zipStream.Write(buffer, 0, length);
                        }
                    }
                }
            }

            foreach (var subDirectory in directory.GetDirectories())
            {
                Recurse(subDirectory, zipStream, rootPath); 
            }
        }
    }
}
